package top.my.api;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.MultiMap;
import io.vertx.core.json.JsonObject;
import io.vertx.example.util.Runner;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.sqlclient.Row;
import io.vertx.sqlclient.RowSet;
import org.apache.log4j.Logger;
import top.my.Const;
import top.my.QueryException;
import top.my.db.QueryRowCallBack;
import top.my.db.RedisServer;
import top.my.db.SqlServer;

import java.util.List;


public class ApiServer extends AbstractVerticle {
    final Logger logger = Logger.getLogger(ApiServer.class);

    // Convenience method so you can run it in your IDE
    public static void main(String[] args) {
        Runner.runExample(ApiServer.class);
    }

    @Override
    public void start() throws Exception {
        logger.info("服务启动初始化");
        Router router = Router.router(vertx);
        router.route().handler(BodyHandler.create());
        startListen(router);
        login(router);
        register(router);
        update(router);
        unregister(router);
        findById(router);
    }


    private void login(Router router) {
        router.post(Const.API_LOGIN).handler(req -> {
            JsonObject json = new JsonObject();
            MultiMap params = req.request().params();
            logger.info("客户端请求body==>" + req.request().params());
            if (!params.contains(Const.USER.USERNAME) || !params.contains(Const.USER.PASSWORD)) {
                json.put(Const.CODE, Const.REP_FAIL);
                json.put(Const.MSG, "登录失败");
                JsonObject data = new JsonObject().put(Const.RESULT, "username或者password为空");
                json.put(Const.DATA, data);
                req.response().end(json.toString());
                logger.info(json.toString());
                return;
            }
            SqlServer.sqlServer.queryBy(Const.DB_USER, params, new QueryRowCallBack() {
                @Override
                public void onComplete(RowSet<Row> resultRows, QueryException exception) {
                    if (exception != null) {
                        json.put(Const.CODE, exception.getCode());
                        if (exception.getCode() == Const.REP_FAIL_NONE) {
                            json.put(Const.MSG, "请检查账号密码重新输入");
                        } else {
                            json.put(Const.MSG, "系统错误");
                        }
                    } else {
                        Row row = resultRows.iterator().next();
                        List<String> columnsNames = resultRows.columnsNames();
                        JsonObject data = new JsonObject();
                        for (int i = 0; i < columnsNames.size(); i++) {
                            Object value = row.getValue(i);
                            if (value != null) {
                                data.put(columnsNames.get(i), value);
                            }
                        }
                        json.put(Const.CODE, Const.REP_SUCCESS);
                        json.put(Const.DATA, data);
                    }
                    req.response().end(json.toString());
                    logger.info(json.toString());
                }
            });
        });
    }//login

    private void register(Router router) {
        router.post(Const.API_REGISTER).handler(req -> {
            JsonObject json = new JsonObject();
            MultiMap params = req.request().params();
            logger.info("客户端请求body==>" + req.request().params());
            if (!params.contains(Const.USER.USERNAME) || !params.contains(Const.USER.PASSWORD)) {
                json.put(Const.CODE, Const.REP_FAIL);
                json.put(Const.MSG, "注册失败");
                JsonObject data = new JsonObject().put(Const.RESULT, "username或者password为空");
                json.put(Const.DATA, data);
                req.response().end(json.toString());
                logger.info(json.toString());
                return;
            }
            params.add("createtime", String.valueOf(System.currentTimeMillis()));
            SqlServer.sqlServer.insertBy(Const.DB_USER, params, new QueryRowCallBack() {
                @Override
                public void onComplete(RowSet<Row> resultRows, QueryException exception) {
                    if (exception != null) {
                        json.put(Const.CODE, exception.getCode());
                        if (exception.getCode() == Const.REP_FAIL) {
                            json.put(Const.MSG, "账号已注册");
                        } else {
                            json.put(Const.MSG, "系统错误");
                        }
                    } else {
                        Row row = resultRows.iterator().next();
                        List<String> columnsNames = resultRows.columnsNames();
                        JsonObject data = new JsonObject();
                        for (int i = 0; i < columnsNames.size(); i++) {
                            Object value = row.getValue(i);
                            if (value != null) {
                                data.put(columnsNames.get(i), value);
                            }
                        }
                        json.put(Const.CODE, Const.REP_SUCCESS);
                        json.put(Const.DATA, data);
                    }
                    req.response().end(json.toString());
                    logger.info(json.toString());
                }
            });
        });
    }//register

    private void update(Router router) {
        router.post(Const.API_UPDATE_INFO).handler(req -> {
            System.out.println("客户端请求body1==>" + req.request().body());
            JsonObject json = new JsonObject();
            MultiMap params = req.request().params();
            System.out.println("客户端请求body==>" + req.request().params());
            String uid = params.get(Const.USER.UID);
            params.remove("username");//防止修改了账号
            params.add("updatetime", String.valueOf(System.currentTimeMillis()));
            if (!params.contains(Const.USER.UID)) {
                json.put(Const.CODE, Const.REP_FAIL);
                json.put(Const.MSG, "修改信息失败");
                JsonObject data = new JsonObject().put(Const.RESULT, "uid为空");
                json.put(Const.DATA, data);
                req.response().end(json.toString());
                return;
            }
            SqlServer.sqlServer.updateBy(Const.DB_USER, params, Const.USER.UID, uid, new QueryRowCallBack() {
                @Override
                public void onComplete(RowSet<Row> resultRows, QueryException exception) {

                    if (exception != null) {
                        json.put(Const.CODE, exception.getCode());
                        if (exception.getCode() == Const.REP_FAIL) {
                            json.put(Const.MSG, "修改信息失败");
                        } else {
                            json.put(Const.MSG, "系统错误");
                        }
                    } else {
                        Row row = resultRows.iterator().next();
                        List<String> columnsNames = resultRows.columnsNames();
                        JsonObject data = new JsonObject();
                        for (int i = 0; i < columnsNames.size(); i++) {
                            Object value = row.getValue(i);
                            if (value != null) {
                                data.put(columnsNames.get(i), value);
                            }
                        }
                        json.put(Const.CODE, Const.REP_SUCCESS);
                        json.put(Const.DATA, data);
                    }
                    req.response().end(json.toString());
                }
            });
        });
    }//update

    private void unregister(Router router) {
        router.post(Const.API_UNREGISTER).handler(req -> {
            JsonObject json = new JsonObject();
            MultiMap params = req.request().params();
            logger.info("客户端请求body==>" + req.request().params());
            if (!params.contains(Const.USER.UID)) {
                json.put(Const.CODE, Const.REP_FAIL);
                json.put(Const.MSG, "删除信息失败");
                JsonObject data = new JsonObject().put(Const.RESULT, "uid为空");
                json.put(Const.DATA, data);
                req.response().end(json.toString());
                return;
            }
            SqlServer.sqlServer.deleteBy(Const.DB_USER, params, new QueryRowCallBack() {
                @Override
                public void onComplete(RowSet<Row> resultRows, QueryException exception) {
                    if (exception != null) {
                        json.put(Const.CODE, exception.getCode());
                        if (exception.getCode() == Const.REP_FAIL) {
                            json.put(Const.MSG, "删除信息失败");
                        } else {
                            json.put(Const.MSG, "系统错误");
                        }
                    } else {
                        JsonObject data = new JsonObject().put(Const.RESULT, "删除成功");
                        json.put(Const.CODE, Const.REP_SUCCESS);
                        json.put(Const.DATA, data);
                    }
                    req.response().end(json.toString());
                }
            });
        });
    }//update

    private void findById(Router router) {
        router.post(Const.API_GET_INFO_BY_ID).handler(req -> {
            RedisServer.redisServer.redis.get("key").onSuccess(value -> {
                logger.info("redis.key==>" + value);
            });
            logger.info("客户端请求body==>" + req.body().asString());
            JsonObject json = new JsonObject();
            MultiMap params = req.request().params();
            if (!params.contains(Const.USER.UID)) {
                json.put(Const.CODE, Const.REP_FAIL);
                json.put(Const.MSG, "获取信息失败");
                JsonObject data = new JsonObject().put(Const.RESULT, "uid为空");
                json.put(Const.DATA, data);
                req.response().end(json.toString());
                logger.info(json.toString());
                return;
            }
            String uid = params.get(Const.USER.UID);
            SqlServer.sqlServer.queryBy(Const.DB_USER, Const.USER.UID, uid, new QueryRowCallBack() {
                @Override
                public void onComplete(RowSet<Row> resultRows, QueryException exception) {
                    if (exception != null) {
                        json.put(Const.CODE, exception.getCode());
                        if (exception.getCode() == Const.REP_FAIL_NONE) {
                            json.put(Const.MSG, "账户不存在");
                        } else {
                            json.put(Const.MSG, "系统错误");
                        }
                    } else {
                        Row row = resultRows.iterator().next();
                        List<String> columnsNames = resultRows.columnsNames();
                        JsonObject data = new JsonObject();
                        for (int i = 0; i < columnsNames.size(); i++) {
                            Object value = row.getValue(i);
                            //if (value != null) {
                                data.put(columnsNames.get(i), value);
                            //}
                        }
                        data.remove("password");
                        data.remove("phone");
                        data.remove("xid");
                        data.remove("mids");
                        data.remove("updatetime");
                        json.put(Const.CODE, Const.REP_SUCCESS);
                        json.put(Const.DATA, data);
                    }
                    req.response().end(json.toString());
                    logger.info(json.toString());
                }
            });
        });
    }//login


    private void findBy(Router router) {
        router.post(Const.API_GET_INFO_BY_ID).handler(req -> {
            JsonObject params = req.body().asJsonObject();
            logger.info("客户端请求body1==>" + req.body().asString());
            JsonObject json = new JsonObject();
            if (!params.containsKey(Const.USER.UID)) {
                json.put(Const.CODE, Const.REP_FAIL);
                json.put(Const.MSG, "获取信息失败");
                JsonObject data = new JsonObject().put(Const.RESULT, "uid为空");
                json.put(Const.DATA, data);
                req.response().end(json.toString());
                return;
            }
            int uid = (int) params.getValue(Const.USER.UID, 0);
            SqlServer.sqlServer.queryBy(Const.DB_USER, Const.USER.UID, uid, new QueryRowCallBack() {
                @Override
                public void onComplete(RowSet<Row> resultRows, QueryException exception) {
                    if (exception != null) {
                        json.put(Const.CODE, exception.getCode());
                        if (exception.getCode() == Const.REP_FAIL_NONE) {
                            json.put(Const.MSG, "账户不存在");
                        } else {
                            json.put(Const.MSG, "系统错误");
                        }
                    } else {
                        Row row = resultRows.iterator().next();
                        List<String> columnsNames = resultRows.columnsNames();
                        JsonObject data = new JsonObject();
                        for (int i = 0; i < columnsNames.size(); i++) {
                            Object value = row.getValue(i);
                            if (value != null) {
                                data.put(columnsNames.get(i), value);
                            }
                        }
                        json.put(Const.CODE, Const.REP_SUCCESS);
                        json.put(Const.DATA, data);
                    }
                    req.response().end(json.toString());
                }
            });
        });
    }//login

    //将Router与vertx HttpServer绑定,开始监听
    private void startListen(Router router) {
        vertx.createHttpServer().requestHandler(router).listen(8080)
                .onSuccess(ar ->
                        logger.info("API服务启动成功")
                ).onFailure(fail ->
                        logger.info("API服务启动失败")
                );
    }//end startListen
}
